package com.nariano.server.domain.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.nariano.server.domain.entities.AreaBoundaries;
import com.nariano.server.domain.entities.Location;

/**
 * Definition av koordinatsystemet
 * 
 * West x=0 ... N-1 East
 * North x=0 ... M-1 South
 * 
 */
public enum Direction {
    North, South, East, West;
    
    static private Random rand = new Random();
    
    @Deprecated // use Direction getRandomDirection(Location location, AreaBoundaries boundaries)
    public static Direction getRandomDirection() {
        Direction dir = Direction.values()[rand.nextInt(Direction.values().length)];
        return dir;
    }
    
    @Deprecated // Use Location getRandomLocation(Location sourceLocation, AreaBoundaries boundaries)
    public Location getRandomLocation(Location sourceLocation) {
        int offset = rand.nextInt(3) - 1;
        return getLocationFromOffset(offset, sourceLocation);

    }
    
    public static Direction getRandomDirection(Location location, AreaBoundaries boundaries) {
		while (true) {
			Direction dir = Direction.values()[rand.nextInt(Direction.values().length)];
			if (location.getX()==0&&dir.equals(West)) { continue; }
			if (location.getX()==boundaries.getWidth()-1&&dir.equals(East)) { continue; }
			if (location.getY()==0&&dir.equals(North)) { continue; }
			if (location.getY()==boundaries.getHeight()-1&&dir.equals(South)) { continue; }
			
			return dir;
		}
	}
    
    public Location getRandomLocation(Location sourceLocation, AreaBoundaries bound) {
    	int offset = rand.nextInt(3) - 1;
        Location loc =  getLocationFromOffset(offset, sourceLocation);
        if (this.equals(North) && (loc.getX()<0||loc.getX()>=bound.getWidth())) {
        	loc.setX(sourceLocation.getX());
        	return loc;
        }
        if (this.equals(South) && (loc.getX()<0||loc.getX()>=bound.getWidth())) {
        	loc.setX(sourceLocation.getX());
        	return loc;
        }

        if (this.equals(West) && (loc.getY()<0||loc.getY()>=bound.getHeight())) {
        	loc.setY(sourceLocation.getY());
        	return loc;
        }
        if (this.equals(East) && (loc.getY()<0||loc.getY()>=bound.getHeight())) {
        	loc.setY(sourceLocation.getY());
        	return loc;
        }
        return loc;
    }
    
    
    @Deprecated // don't use
    public List<Location> getRandomLocationList(Location sourceLocation) {
        List<Location> res = new ArrayList<Location>(3);
        int index = rand.nextInt(1000000);
        for (int i = index; i<index+2; i++) {
            int offset = (i % 3) - 1;
            res.add(getLocationFromOffset(offset, sourceLocation));
        }
        return res;
    }

    private Location getLocationFromOffset(int offset, Location sourceLocation) {
        Location loc = null;
        if (Direction.East.equals(this)) {
            loc = new Location(sourceLocation.getX() + 1, sourceLocation.getY() + offset);
        } else if (Direction.North.equals(this)) {
            loc = new Location(sourceLocation.getX() + offset, sourceLocation.getY() - 1);
        } else if (Direction.South.equals(this)) {
            loc = new Location(sourceLocation.getX() + offset, sourceLocation.getY() + 1);
        } else if (Direction.West.equals(this)) {
            loc = new Location(sourceLocation.getX() -1, sourceLocation.getY() + offset);
        }
        return loc;
    }

	
}
